package com.material.vtool.exception;

import com.material.vtool.entity.respEntity.RespData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;

/**
 * @author junya
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(value = Exception.class)
    public RespData defaultErrorHandler(HttpServletRequest req, Exception ex) {

        String requestURI = req.getRequestURI();

        Integer statusCode = getStatus(req).value();

        /*错误日志输出到控制台，此处不能使用slf4j，否则无法输出日志信息*/
        String errMsg = ex.getMessage();
        logger.error("[exceptReqUrl] = " + requestURI + " " + errMsg + " [statusCode] = " + statusCode, ex);

        //打印堆栈信息 -- 直接 ex.printStackTrace(); 无法打印堆栈
        //ex.printStackTrace();

        RespData respData = new RespData();
        respData.setCode(500);
        respData.setMsg("加载中…如时间较长，建议您重新进入.");

        return respData;
    }

    /**
     * 404异常
     *
     * @since 2018/12/6
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    public RespData noHandlerFoundException() {
        RespData respData = new RespData();
        respData.setCode(404);
        respData.setMsg("该服务不存在");
        return respData;
    }

    /**
     * 服务异常
     *
     * @since 2018/12/6
     */
    @ExceptionHandler(ServiceException.class)
    public RespData serviceException(ServiceException e) {
        RespData respData = new RespData();
        respData.setCode(e.getCode());
        respData.setMsg(e.getMessage());

        return respData;
    }

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        return HttpStatus.valueOf(statusCode);
    }

}
